package com.jiaying.sync;

import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.*;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.UpdateOptions;
import com.mongodb.client.model.UpdateOneModel;
import com.mongodb.client.model.WriteModel;
import com.mongodb.client.model.BulkWriteOptions;
import org.bson.Document;
import org.bson.conversions.Bson;

import com.jiaying.sync.config.MongoConfig;
import com.jiaying.sync.beans.SmsContentForm;
import com.jiaying.sync.beans.SmsMobilesForm;
import com.jiaying.sync.utils.SnowflakeIdWorkerOptimize; // 添加雪花ID生成器导入
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.CountDownLatch;

/**
 * 数据插入测试类
 * 使用MongoClusterTest的连接信息，向MongoDB插入测试数据
 * 使用线程池实现并发插入数据
 */
public class DataInsertionTest {
    private static final Logger logger = LoggerFactory.getLogger(DataInsertionTest.class);
    
    private MongoClient mongoClient;
    private MongoConfig mongoConfig;
    private Random random = new Random();
    private volatile boolean running = true;
    private AtomicInteger totalCount = new AtomicInteger(0);
    private AtomicInteger lastSecondCount = new AtomicInteger(0); // 用于统计每秒插入的数据量
    
    // 可配置参数
    private static final int DEFAULT_THREAD_COUNT = 50; // 默认线程池大小
    private static final int DEFAULT_BATCH_SIZE = 200; // 默认批量插入大小
    private static final int DEFAULT_INSERT_COUNT = 1000000; // 默认插入数据量
    
    private int threadCount = DEFAULT_THREAD_COUNT; // 线程池大小
    private int batchSize = DEFAULT_BATCH_SIZE; // 批量插入大小
    private int targetInsertCount = DEFAULT_INSERT_COUNT; // 目标插入数据量
    
    // 添加雪花ID生成器实例
    private SnowflakeIdWorkerOptimize idWorker = new SnowflakeIdWorkerOptimize(0, 0);
    
    public static void main(String[] args) {
        DataInsertionTest tester = new DataInsertionTest();
        
        // 解析命令行参数
        tester.parseArguments(args);
        
        // 添加关闭钩子以优雅关闭
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            logger.info("\n接收到关闭信号，正在停止数据插入...");
            tester.stop();
        }));
        
        try {
            tester.initializeConnections();
            tester.insertTestDataConcurrently();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            tester.closeConnections();
        }
    }
    
    /**
     * 解析命令行参数
     * @param args 命令行参数
     */
    private void parseArguments(String[] args) {
        for (int i = 0; i < args.length; i++) {
            switch (args[i]) {
                case "-c":
                case "--count":
                    if (i + 1 < args.length) {
                        try {
                            int count = Integer.parseInt(args[++i]);
                            if (count > 0) {
                                this.targetInsertCount = count;
                            } else {
                                System.err.println("插入数据量必须大于0，使用默认值: " + DEFAULT_INSERT_COUNT);
                            }
                        } catch (NumberFormatException e) {
                            logger.error("无效的插入数据量参数，使用默认值: {}", DEFAULT_INSERT_COUNT);
                        }
                    }
                    break;
                case "-t":
                case "--threads":
                    if (i + 1 < args.length) {
                        try {
                            int threads = Integer.parseInt(args[++i]);
                            if (threads > 0 && threads <= 200) {
                                this.threadCount = threads;
                            } else {
                                System.err.println("线程数必须在1-200之间，使用默认值: " + DEFAULT_THREAD_COUNT);
                            }
                        } catch (NumberFormatException e) {
                            logger.error("无效的线程数参数，使用默认值: {}", DEFAULT_THREAD_COUNT);
                        }
                    }
                    break;
                case "-b":
                case "--batch":
                    if (i + 1 < args.length) {
                        try {
                            int batch = Integer.parseInt(args[++i]);
                            if (batch > 0 && batch <= 10000) {
                                this.batchSize = batch;
                            } else {
                                System.err.println("批量大小必须在1-10000之间，使用默认值: " + DEFAULT_BATCH_SIZE);
                            }
                        } catch (NumberFormatException e) {
                            logger.error("无效的批量大小参数，使用默认值: {}", DEFAULT_BATCH_SIZE);
                        }
                    }
                    break;
                case "-h":
                case "--help":
                    printUsage();
                    System.exit(0);
                    break;
                default:
                    logger.error("未知参数: {}", args[i]);
                    printUsage();
                    System.exit(1);
            }
        }
        
        logger.info("配置参数:");
        logger.info("  线程数: {}", this.threadCount);
        logger.info("  批量大小: {}", this.batchSize);
        logger.info("  目标插入数据量: {}", this.targetInsertCount);
    }
    
    /**
     * 打印使用说明
     */
    private void printUsage() {
        logger.info("使用方法: java DataInsertionTest [选项]");
        logger.info("选项:");
        logger.info("  -c, --count <数量>     设置插入数据量 (默认: {})", DEFAULT_INSERT_COUNT);
        logger.info("  -t, --threads <数量>   设置线程数 (默认: {}, 范围: 1-200)", DEFAULT_THREAD_COUNT);
        logger.info("  -b, --batch <数量>     设置批量大小 (默认: {}, 范围: 1-10000)", DEFAULT_BATCH_SIZE);
        logger.info("  -h, --help             显示此帮助信息");
    }
    
    /**
     * 初始化MongoDB连接
     */
    public void initializeConnections() {
        try {
            // 初始化MongoDB配置和连接
            mongoConfig = new MongoConfig();
            String connectionString = "mongodb://" + mongoConfig.getClusterHosts();
            
            MongoClientSettings settings = MongoClientSettings.builder()
                    .applyConnectionString(new ConnectionString(connectionString))
                    .applyToClusterSettings(builder -> 
                        builder.serverSelectionTimeout(mongoConfig.getServerSelectionTimeoutMs(), TimeUnit.MILLISECONDS))
                    .applyToSocketSettings(builder -> 
                        builder.connectTimeout(mongoConfig.getConnectionTimeoutMs(), TimeUnit.MILLISECONDS)
                               .readTimeout(mongoConfig.getSocketTimeoutMs(), TimeUnit.MILLISECONDS))
                    .applyToConnectionPoolSettings(builder ->
                        builder.maxSize(mongoConfig.getMaxConnectionPoolSize())
                               .minSize(mongoConfig.getMinConnectionPoolSize())
                               .maxWaitTime(10, TimeUnit.SECONDS))
                    .build();
            
            mongoClient = MongoClients.create(settings);
            logger.info("成功连接到MongoDB集群: {}", mongoConfig.getClusterHosts());
            
        } catch (Exception e) {
            logger.error("初始化连接失败: {}", e.getMessage(), e);
            throw e;
        }
    }
    
    /**
     * 使用线程池并发插入测试数据
     */
    public void insertTestDataConcurrently() {
        logger.info("开始并发插入测试数据...");
        logger.info("目标插入数据量: {} 条", targetInsertCount);
        logger.info("线程数: {}", threadCount);
        logger.info("批量大小: {}", batchSize);
        logger.info("按 Ctrl+C 停止程序");
        
        // 创建固定大小的线程池
        ExecutorService executorService = Executors.newFixedThreadPool(threadCount);
        
        // 记录开始时间
        long startTime = System.currentTimeMillis();
        
        // 启动统计线程，每秒输出一次插入数据量
        ExecutorService statsService = Executors.newSingleThreadExecutor();
        statsService.submit(() -> {
            while (running) {
                try {
                    Thread.sleep(1000);
                    int currentCount = totalCount.get();
                    int lastCount = lastSecondCount.getAndSet(currentCount);
                    int perSecond = currentCount - lastCount;
                    logger.info("总计插入: {} 条, 本秒插入: {} 条", currentCount, perSecond);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        });
        
        try {
            // 提交任务到线程池
            for (int i = 0; i < threadCount; i++) {
                final int threadId = i;
                executorService.submit(() -> {
                    while (running) {
                        try {
                            // 原子性地尝试增加计数器
                            int currentCount = totalCount.get();
                            
                            // 检查是否已达到目标插入量
                            if (currentCount >= targetInsertCount) {
                                break;
                            }
                            
                            // 计算可以插入的数据量（不超过目标数量）
                            int remainingCount = targetInsertCount - currentCount;
                            if (remainingCount <= 0) {
                                break;
                            }
                            
                            // 随机选择插入方式：0-单条插入，1-批量插入
                            if (random.nextInt(2) == 0 || remainingCount < batchSize) {
                                // 尝试原子性地增加计数器，确保不超过目标数量
                                int newCount = currentCount + 1;
                                if (newCount <= targetInsertCount && totalCount.compareAndSet(currentCount, newCount)) {
                                    // 单条插入
                                    insertRandomMongoDBTestDataWithUpsert(threadId);
                                }
                            } else {
                                // 计算实际批量大小（不超过剩余需要插入的数据量和目标数量）
                                int actualBatchSize = Math.min(batchSize, remainingCount);
                                int newCount = currentCount + actualBatchSize;
                                if (newCount <= targetInsertCount && totalCount.compareAndSet(currentCount, newCount)) {
                                    insertRandomMongoDBTestDataBatch(threadId, actualBatchSize);
                                }
                            }
                            
                            // 控制插入频率，避免过载
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            logger.info("线程 {} 被中断", threadId);
                            Thread.currentThread().interrupt();
                            break;
                        } catch (Exception e) {
                            logger.error("线程 {} 插入测试数据失败: {}", threadId, e.getMessage(), e);
                        }
                    }
                });
            }
            
            // 等待直到收到停止信号或达到目标插入量
            while (running && totalCount.get() < targetInsertCount) {
                Thread.sleep(1000);
            }
            
            // 如果是达到目标插入量而停止，则设置running为false以停止所有线程
            if (totalCount.get() >= targetInsertCount) {
                logger.info("已达到目标插入数据量: {} 条，正在停止...", targetInsertCount);
                running = false;
            }
        } catch (InterruptedException e) {
            logger.info("监控线程被中断");
            Thread.currentThread().interrupt();
        } finally {
            // 关闭线程池
            executorService.shutdown();
            statsService.shutdown();
            try {
                if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
                    executorService.shutdownNow();
                }
                if (!statsService.awaitTermination(5, TimeUnit.SECONDS)) {
                    statsService.shutdownNow();
                }
            } catch (InterruptedException e) {
                executorService.shutdownNow();
                statsService.shutdownNow();
                Thread.currentThread().interrupt();
            }
        }
        
        long endTime = System.currentTimeMillis();
        long elapsedSeconds = (endTime - startTime) / 1000;
        logger.info("总共运行 {} 秒，插入了 {} 条记录", elapsedSeconds, totalCount.get());
    }
    
    /**
     * 批量插入MongoDB测试数据
     */
    private void insertRandomMongoDBTestDataBatch(int threadId, int batchSize) {
        try {
            MongoDatabase database = mongoClient.getDatabase(mongoConfig.getDatabaseName());
            
            // 随机选择插入哪种类型的文档
            if (random.nextBoolean()) {
                MongoCollection<Document> collectionContent = database.getCollection("TBL_SMS_CONTENT_20251221");
                List<WriteModel<Document>> writeModels = new ArrayList<>();
                
                // 创建批量插入数据
                for (int i = 0; i < batchSize; i++) {
                    SmsContentForm contentForm = createRandomSmsContentForm(threadId * batchSize + i);
                    Document contentDoc = convertSmsContentFormToDocument(contentForm);
                    
                    // 创建查询条件
                    Bson query = Filters.eq("_id", contentDoc.get("_id"));
                    
                    // 创建更新文档，包含所有字段和$updateTime
                    Document updateDocument = new Document("$set", contentDoc)
                            .append("$currentDate", new Document("updateTime", true));
                    
                    // 创建upsert操作
                    UpdateOneModel<Document> uom = new UpdateOneModel<>(query, updateDocument, new UpdateOptions().upsert(true));
                    writeModels.add(uom);
                }
                
                // 执行批量upsert操作
                collectionContent.bulkWrite(writeModels, new BulkWriteOptions().ordered(false));
                // System.out.println("线程 " + threadId + " - 批量插入 " + batchSize + " 条SmsContentForm数据成功");
            } else {
                MongoCollection<Document> collectionMobile = database.getCollection("TBL_SMS_MOBILES_20251221");
                List<WriteModel<Document>> writeModels = new ArrayList<>();
                
                // 创建批量插入数据
                for (int i = 0; i < batchSize; i++) {
                    SmsMobilesForm mobilesForm = createRandomSmsMobilesForm(threadId * batchSize + i);
                    Document mobileDoc = convertSmsMobilesFormToDocument(mobilesForm);
                    
                    // 创建查询条件
                    Bson query = Filters.eq("_id", mobileDoc.get("_id"));
                    
                    // 创建更新文档，包含所有字段和$updateTime
                    Document updateDocument = new Document("$set", mobileDoc)
                            .append("$currentDate", new Document("updateTime", true));
                    
                    // 创建upsert操作
                    UpdateOneModel<Document> uom = new UpdateOneModel<>(query, updateDocument, new UpdateOptions().upsert(true));
                    writeModels.add(uom);
                }
                
                // 执行批量upsert操作
                collectionMobile.bulkWrite(writeModels, new BulkWriteOptions().ordered(false));
                // System.out.println("线程 " + threadId + " - 批量插入 " + batchSize + " 条SmsMobilesForm数据成功");
            }
        } catch (Exception e) {
            logger.error("批量插入MongoDB测试数据失败: {}", e.getMessage(), e);
        }
    }
    
    /**
     * 停止数据插入
     */
    public void stop() {
        running = false;
    }
    
    /**
     * 使用upsert操作一次性插入数据并设置时间戳
     */
    private void insertRandomMongoDBTestDataWithUpsert(int threadId) {
        try {
            MongoDatabase database = mongoClient.getDatabase(mongoConfig.getDatabaseName());
            
            // 随机选择插入哪种类型的文档
            if (random.nextBoolean()) {
                MongoCollection<Document> collectionContent = database.getCollection("TBL_SMS_CONTENT_20251221");
                // 使用SmsContentForm构建数据
                SmsContentForm contentForm = createRandomSmsContentForm(threadId);
                Document contentDoc = convertSmsContentFormToDocument(contentForm);
                
                // 创建查询条件
                Bson query = Filters.eq("_id", contentDoc.get("_id"));
                
                // 创建更新文档，包含所有字段和$updateTime
                Document updateDocument = new Document("$set", contentDoc)
                        .append("$currentDate", new Document("updateTime", true));
                
                // 执行upsert操作
                collectionContent.updateOne(query, updateDocument, new UpdateOptions().upsert(true));
                // System.out.println("线程 " + threadId + " - MongoDB SmsContentForm数据upsert成功，ID: " + contentDoc.get("_id"));
            } else {
                MongoCollection<Document> collectionMobile = database.getCollection("TBL_SMS_MOBILES_20251221");
                // 使用SmsMobilesForm构建数据
                SmsMobilesForm mobilesForm = createRandomSmsMobilesForm(threadId);
                Document mobileDoc = convertSmsMobilesFormToDocument(mobilesForm);
                
                // 创建查询条件
                Bson query = Filters.eq("_id", mobileDoc.get("_id"));
                
                // 创建更新文档，包含所有字段和$updateTime
                Document updateDocument = new Document("$set", mobileDoc)
                        .append("$currentDate", new Document("updateTime", true));
                
                // 执行upsert操作
                collectionMobile.updateOne(query, updateDocument, new UpdateOptions().upsert(true));
                // System.out.println("线程 " + threadId + " - MongoDB SmsMobilesForm数据upsert成功，ID: " + mobileDoc.get("_id"));
            }
            
        } catch (Exception e) {
            logger.error("插入MongoDB测试数据失败: {}", e.getMessage(), e);
        }
    }
    
    /**
     * 创建随机SmsContentForm对象
     * 只包含TBL_SMS_CONTENT_20251221表中的字段
     */
    private SmsContentForm createRandomSmsContentForm(int threadId) {
        SmsContentForm form = new SmsContentForm();
        
        // 使用雪花ID生成器生成ID
        long id = idWorker.nextId();
        form.setId(id);
        form.setAddtime(new Date());
        form.setContent("测试短信内容_" + threadId + "_" + System.currentTimeMillis());
        form.setmGateway(random.nextInt(5));
        form.setMobileCount(random.nextInt(100));
        form.setMsgCount(random.nextInt(10));
        form.setSendTime(new Date());
        form.setSource(random.nextInt(3) + 1);
        form.setStatus(random.nextInt(5) - 1);
        form.setStatusCode(String.format("%06d", random.nextInt(1000000)));
        form.settGateway(random.nextInt(5));
        form.setEprId(random.nextInt(1000));
        form.setUcuid("user" + random.nextInt(1000));
        form.setuGateway(random.nextInt(5));
        form.setPriority(random.nextInt(10));
        // 修正md5Content字段长度问题，确保不超过16个字符
        String contentForMd5 = "测试短信内容_" + threadId + "_" + System.currentTimeMillis();
        form.setMd5Content(generateShortMd5(contentForMd5));
        form.setPlatform(random.nextInt(3));
        form.setCtxtype(random.nextInt(2));
        form.setTempID(random.nextInt(1000));
        form.setContentType(random.nextInt(10));
        form.setTaskId(random.nextInt(10000));
        form.setCustTempId(random.nextInt(1000));
        form.setTiming(random.nextInt(2));
        form.setHfType(random.nextInt(4));
        form.setOnlyId(id + 2000000);
        
        return form;
    }
    
    /**
     * 创建随机SmsMobilesForm对象
     * 只包含TBL_SMS_MOBILES_20251221表中的字段
     */
    private SmsMobilesForm createRandomSmsMobilesForm(int threadId) {
        SmsMobilesForm form = new SmsMobilesForm();
        
        // 使用雪花ID生成器生成ID
        long id = idWorker.nextId();
        form.setId(id);
        // 修正clientMsgid字段长度问题，确保不超过32个字符
        form.setClientMsgid(generateFixedLengthString("client_" + threadId + "_" + System.currentTimeMillis(), 32));
        form.setDisplayNum("100" + random.nextInt(900));
        form.setExtNum(String.valueOf(random.nextInt(100)));
        form.setGateway(random.nextInt(5));
        form.setMobile("138" + String.format("%08d", random.nextInt(100000000)));
        form.setMsgCount(random.nextInt(5));
        // 修正msgid字段长度问题，确保不超过48个字符
        form.setMsgid(generateFixedLengthString("msg_" + threadId + "_" + System.currentTimeMillis(), 48));
        
        // 使用setScale来避免Decimal128转换错误
        form.setPrice(new BigDecimal(random.nextDouble() * 10).setScale(6, java.math.RoundingMode.HALF_UP));
        form.setPriority(random.nextInt(10));
        form.setResend(random.nextInt(3));
        form.setResult(String.valueOf(random.nextInt(3)));
        form.setSendTime(new Date());
        form.setStatus(random.nextInt(5) - 1);
        form.setStatusCode(String.format("%06d", random.nextInt(1000000)));
        form.setUcuid("user" + random.nextInt(1000));
        form.setEprId(random.nextInt(1000));
        form.setCid(id + 3000000);
        form.setMobileType(random.nextInt(5));
        
        // 使用setScale来避免Decimal128转换错误
        form.setTotalPrice(new BigDecimal(random.nextDouble() * 100).setScale(6, java.math.RoundingMode.HALF_UP));
        form.setTotalCost(new BigDecimal(random.nextDouble() * 50).setScale(6, java.math.RoundingMode.HALF_UP));
        
        form.setDeliverdTime(new Date(System.currentTimeMillis() + random.nextInt(3600000)));
        // 修正area字段长度问题，确保不超过30个字符
        form.setArea(generateFixedLengthString("地区_" + threadId + "_" + System.currentTimeMillis(), 30));
        form.setCtxtype(random.nextInt(2));
        form.setAddStatusTime(new Date());
        form.setPlatform(random.nextInt(3));
        form.setTempID(random.nextInt(1000));
        form.setContentType(random.nextInt(10));
        form.setExFlag(random.nextInt(2));
        // 修正city字段长度问题，确保不超过50个字符
        form.setCity(generateFixedLengthString("城市_" + threadId + "_" + System.currentTimeMillis(), 50));
        form.setTaskId(random.nextInt(10000));
        form.setCustTempId(random.nextInt(1000));
        // 修正linkman字段长度问题，确保不超过32个字符
        form.setLinkman(generateFixedLengthString("联系人_" + threadId + "_" + System.currentTimeMillis(), 32));
        form.setMpResend(random.nextInt(8));
        form.setMsgLen(random.nextInt(1000));
        form.setHfType(random.nextInt(4));
        form.setOnlyId(id + 4000000);
        form.setAreaId(random.nextInt(50));
        // 修正content字段长度问题，确保不超过2000个字符
        form.setContent(generateFixedLengthString("内容_" + threadId + "_" + System.currentTimeMillis(), 2000));
        form.setOriginalId(id + 5000000);
        form.setOriginalSendTime(new Date(System.currentTimeMillis() - random.nextInt(3600000)));
        form.setParentId(id + 6000000);
        form.setParentIdSendTime(new Date(System.currentTimeMillis() - random.nextInt(7200000)));
        form.setReSendTimes(random.nextInt(10));
        form.setResendMode(random.nextInt(4));
        form.setResendMbType(random.nextInt(5));
        
        return form;
    }
    
    /**
     * 将SmsContentForm转换为MongoDB Document
     * 只包含TBL_SMS_CONTENT_20251221表中的字段
     * 不再手动添加updateTime字段，而是使用MongoDB的upsert操作
     */
    private Document convertSmsContentFormToDocument(SmsContentForm form) {
        Document doc = new Document();
        doc.append("_id", form.getId());
        doc.append("content", form.getContent());
        doc.append("sendTime", form.getSendTime());
        doc.append("addTime", form.getAddtime());
        doc.append("mobileCount", form.getMobileCount());
        doc.append("msgCount", form.getMsgCount());
        doc.append("mgateway", form.getmGateway());
        doc.append("tgateway", form.gettGateway());
        doc.append("ugateway", form.getuGateway());
        doc.append("status", form.getStatus());
        doc.append("ucuid", form.getUcuid());
        doc.append("source", form.getSource());
        doc.append("eprId", form.getEprId());
        doc.append("priority", form.getPriority());
        doc.append("md5Content", form.getMd5Content());
        doc.append("statusCode", form.getStatusCode());
        doc.append("platform", form.getPlatform());
        doc.append("tempId", form.getTempID());
        doc.append("contentType", form.getContentType());
        doc.append("taskId", form.getTaskId());
        doc.append("custTempId", form.getCustTempId());
        doc.append("timing", form.getTiming());
        doc.append("hfType", form.getHfType());
        doc.append("onlyId", form.getOnlyId());
        // doc.append("ctxtype", form.getCtxtype());
        // 不再手动添加updateTime字段，而是使用MongoDB的upsert操作
        return doc;
    }
    
    /**
     * 将SmsMobilesForm转换为MongoDB Document
     * 只包含TBL_SMS_MOBILES_20251221表中的字段
     * 不再手动添加updateTime字段，而是使用MongoDB的upsert操作
     */
    private Document convertSmsMobilesFormToDocument(SmsMobilesForm form) {
        Document doc = new Document();
        doc.append("_id", form.getId());
        doc.append("mobile", form.getMobile());
        doc.append("cid", form.getCid());
        doc.append("gateway", form.getGateway());
        doc.append("status", form.getStatus());
        doc.append("result", form.getResult());
        doc.append("statusCode", form.getStatusCode());
        doc.append("sendTime", form.getSendTime());
        doc.append("ucuid", form.getUcuid());
        doc.append("price", form.getPrice());
        doc.append("msgcount", form.getMsgCount());
        doc.append("displayNum", form.getDisplayNum());
        doc.append("extNum", form.getExtNum());
        doc.append("reSend", form.getResend());
        doc.append("clientMsgId", form.getClientMsgid());
        doc.append("msgId", form.getMsgid());
        doc.append("priority", form.getPriority());
        doc.append("eprId", form.getEprId());
        doc.append("areaId", form.getAreaId());
        doc.append("mobileType", form.getMobileType());
        doc.append("linkman", form.getLinkman());
        doc.append("totalPrice", form.getTotalPrice());
        doc.append("totalCost", form.getTotalCost());
        doc.append("deliverdTime", form.getDeliverdTime());
        doc.append("ctxType", form.getCtxtype());
        doc.append("content", form.getContent());
        doc.append("addStatusTime", form.getAddStatusTime());
        doc.append("platform", form.getPlatform());
        doc.append("area", form.getArea());
        doc.append("tempId", form.getTempID());
        doc.append("contentType", form.getContentType());
        doc.append("exFlag", form.getExFlag());
        doc.append("city", form.getCity());
        doc.append("taskId", form.getTaskId());
        doc.append("custTempId", form.getCustTempId());
        doc.append("onlyId", form.getOnlyId());
        doc.append("mpResend", form.getMpResend());
        doc.append("msgLen", form.getMsgLen());
        doc.append("hfType", form.getHfType());
        doc.append("resendMbType", form.getResendMbType());
        doc.append("originalId", form.getOriginalId());
        doc.append("originalSendTime", form.getOriginalSendTime());
        doc.append("parentId", form.getParentId());
        doc.append("parentIdSendTime", form.getParentIdSendTime());
        doc.append("reSendTimes", form.getReSendTimes());
        doc.append("resendMode", form.getResendMode());
        // 不再手动添加updateTime字段，而是使用MongoDB的upsert操作
        return doc;
    }
    
    /**
     * 关闭连接
     */
    public void closeConnections() {
        // 关闭MongoDB连接
        if (mongoClient != null) {
            try {
                mongoClient.close();
                logger.info("MongoDB连接已安全关闭");
            } catch (Exception e) {
                logger.error("关闭MongoDB连接时发生错误: {}", e.getMessage(), e);
            }
        }
    }
    
    /**
     * 生成短MD5值（前16位）
     * @param input 输入字符串
     * @return 16位MD5值
     */
    private String generateShortMd5(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] digest = md.digest(input.getBytes());
            
            // 将字节数组转换为十六进制字符串
            StringBuilder sb = new StringBuilder();
            for (byte b : digest) {
                sb.append(String.format("%02x", b & 0xff));
            }
            
            // 返回前16位
            return sb.toString().substring(0, 16);
        } catch (NoSuchAlgorithmException e) {
            // 如果MD5算法不可用，则生成一个简单的16位字符串
            return String.format("%016d", Math.abs(input.hashCode())).substring(0, 16);
        }
    }
    
    /**
     * 生成固定长度的字符串，如果超过指定长度则截断，如果不足则保持原样
     * @param input 输入字符串
     * @param maxLength 最大长度
     * @return 固定长度的字符串
     */
    private String generateFixedLengthString(String input, int maxLength) {
        if (input == null) {
            return "";
        }
        
        if (input.length() <= maxLength) {
            return input;
        }
        
        return input.substring(0, maxLength);
    }
}